package com.haodou.util.widget;

import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.GestureDetector.OnGestureListener;
import android.view.animation.TranslateAnimation;
import android.widget.ListView;

/**
 * 有弹性的ListView(2.3后ListView有这个功能)
 * @author pengjianbo <pengjianbosoft@gmail.com>
 *
 */
public class BouncyListView extends ListView {

	private boolean outBound = false;
	
	private int distance;
	
	private int firstOut;

	public BouncyListView(Context c) {
		super(c);
	}

	public BouncyListView(Context c, AttributeSet attrs) {
		super(c, attrs);
	}

	public BouncyListView(Context c, AttributeSet attrs, int defStyle) {
		super(c, attrs, defStyle);
	}

	GestureDetector gestureDetector = new GestureDetector(
			new OnGestureListener() {

				@Override
				public boolean onDown(MotionEvent e) {
					// TODO Auto-generated method stub
					return false;
				}

				@Override
				public boolean onFling(MotionEvent e1, MotionEvent e2,
						float velocityX, float velocityY) {
					// TODO Auto-generated method stub
					return false;
				}

				@Override
				public void onLongPress(MotionEvent e) {
					// TODO Auto-generated method stub

				}

				@Override
				public boolean onScroll(MotionEvent e1, MotionEvent e2,
						float distanceX, float distanceY) {
					int firstPos = getFirstVisiblePosition();
					int lastPos = getLastVisiblePosition();
					int itemCount = getCount();
					if (outBound && firstPos != 0 && lastPos != (itemCount - 1)) {
						scrollTo(0, 0);
						return false;
					}
					View firstView = getChildAt(firstPos);
					View lastView = getChildAt(lastPos-1);
					if (!outBound) {
						firstOut = (int) e2.getRawX();
					}
					if (firstView != null
							&& (outBound || (firstPos == 0
									&& firstView.getTop() == 0 && distanceY < 0))) {
						distance = (int) (firstOut - e2.getRawY());
						scrollBy(0, distance / 2);
						return true;
					}
					if (lastView == null&&(outBound || (lastPos == itemCount - 1 && distanceY > 0))) {
						Log.d("bottom", "bottom");
						distance = (int) ((itemCount-1)/2 - e2.getRawY());
						scrollBy(0, distance/2);
						return true;
					}
					return false;
				}

				@Override
				public void onShowPress(MotionEvent e) {
					// TODO Auto-generated method stub

				}

				@Override
				public boolean onSingleTapUp(MotionEvent e) {
					// TODO Auto-generated method stub
					return false;
				}
			});

	/**
	 * 最早响应触屏事件，按下和释放响应两次
	 */
	public boolean dispatchTouchEvent(MotionEvent ev) {
		if(getFirstVisiblePosition()==0){
			int act = ev.getAction();
			if ((act == MotionEvent.ACTION_UP || act == MotionEvent.ACTION_CANCEL)
					&& outBound) {
				outBound = false;
			}
			if (!gestureDetector.onTouchEvent(ev)) {
				outBound = false;
			} else {
				outBound = true;
			}
			Rect rect = new Rect();
			getLocalVisibleRect(rect);
			TranslateAnimation am = new TranslateAnimation(0, 0, -rect.top, 0);
			am.setDuration(300);
			startAnimation(am);
			scrollTo(0, 0);
		}
		Log.d("getLastVisiblePosition()", getLastVisiblePosition()+"");
		Log.d("getCount()", getCount()+"");
		if(getLastVisiblePosition()==getCount()-1){
			int act = ev.getAction();
			if ((act == MotionEvent.ACTION_DOWN || act == MotionEvent.ACTION_CANCEL)
					&& outBound) {
				outBound = false;
			}
			if (!gestureDetector.onTouchEvent(ev)) {
				outBound = false;
			} else {
				outBound = true;
			}
			if(outBound){
				Rect rect1 = new Rect();
				getLocalVisibleRect(rect1);
				TranslateAnimation am1 = new TranslateAnimation(0, 0, (-rect1.top-rect1.bottom)/2, getCount()-1);
				am1.setDuration(300);
				startAnimation(am1);
				scrollTo(0, 0);
			}
		}
		return super.dispatchTouchEvent(ev);
	};

}
